package net.flyinggroup.reactor.handson.fn;

import net.flyinggroup.util.exception.FlyingRuntimeException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.util.function.Tuples;

@Configuration
public class FibonacciConfigurer {
    @Bean
    RouterFunction<ServerResponse> fibonacciEndpoint() {
        Flux<Long> fibonacciGenerator = Flux.generate(() -> Tuples.of(0L, 1L),
                (state, sink) -> {
                    if (state.getT1() < 0)
                        sink.error(new FlyingRuntimeException("out of bound"));
//                        sink.complete();
                    else
                        sink.next(state.getT1());
                    return Tuples.of(state.getT2(), state.getT1() + state.getT2());
                });
        return RouterFunctions.route(RequestPredicates.path("/fibo"),
                request -> ServerResponse.ok().body(BodyInserters.fromPublisher(fibonacciGenerator, Long.class)));
    }
}
